\clearemptydoublepages
\chapter{Implémentation}
Dans ce chapitre, nous verrons les méthodes utilisées pour rechercher les
éléments nécessaires au projet dans Xenomai.

\section{Méthodes de recherche}
\paragraph{}
Afin de pouvoir travailler aisément sur le code de Xenomai se trouvant sur l'ARTiGO, un serveur
\textit{ssh} ainsi qu'un serveur X ont été installés sur ce dernier.
Ceci permet, par une redirection X, de travailler directement sur un IDE (Geany)
distant. Il aurait aussi été possible de travailler sur les fichiers distants à
l'aide d'un éditeur local. Toutefois cette méthode n'est pas convaincante
puisque les liens (soft links) se trouvant dans les dossiers du noyau
pourraient alors n'être pas fonctionnels. Cette petite parenthèse nous permet d'arriver dans le vif
du sujet, c'est-à-dire la recherche
d'éléments dans le noyau Xenomai.
\paragraph{}
Grâce à l'éditeur, il devient possible de suivre les liens par un simple clic
sur le label représentant une variable ou une fonction et d'arriver par exemple
à sa définition. Ceci permet un gain de temps évident lorsque l'on a sous les
yeux une variable d'une structure dont le type a été renommé via un typedef et
qui lui-même contient une queue d'objet, etc.
\paragraph{}
Pour les éléments ne se trouvant pas dans les fichiers ouverts de l'éditeur (inutile de charger
des centaines de fichiers) l'outil \textit{grep} permettant de trouver les fichiers contenant un
texte donné ou encore \textit{find} permettant de rechercher les fichiers par nom, son des alliés
indispensables.
\paragraph{}
Mais avant de naviguer, le début de toute recherche commence par une lecture des
fonctions de l'API. Par exemple, il a été aisé de trouver la fonction s'occupant
de l'ordonnancement nommée \flqq schedule\frqq.
\paragraph{}
Il est aussi indispensable, pour la recherche d'éléments de se demander dans
quelles fonctions ces derniers peuvent être utilisés. En effet, par exemple, il
est presque certain qu'une queue a déjà des méthodes permettant d'y prélever des
objets et que ces méthodes sont déjà utilisées dans une fonction. En trouvant ce code, il devient
facile de s'inspirer de l'existant. Pour ce faire, il suffit de lancer
une recherche de l'élément recherché, dans tous les fichiers afin de savoir où
il est utilisé et comment. Effectivement, il est plus que recommandé d'utiliser
les méthodes déjà disponibles pour traiter des éléments, puisque ceux-ci sont
souvent définis de plusieurs façons selon les options du noyau
choisies.
\paragraph{}
N'ayant de debeuggeur à disposition c.f.\ref{ProblemesRencontre}, tous les tests
sont effectués à l'aide de l'instruction \textit{printk}. Sa sortie est alors visualisable
dans le fichier /var/log/messages. Afin de pouvoir visionner uniquement les derniers messages du
fichier
de log, le script suivant a été créé :
\lstset{language=bash}
\begin{lstlisting}[frame=trbl]
#! /bin/bash
tail -n $1 /var/log/messages | more
\end{lstlisting}
Ce dernier permet d'afficher le nombre de lignes désirées et de pouvoir les faire défiler en
appuyant sur la touche \flqq enter\frqq.
\paragraph{}
Afin de pouvoir activer / désactiver ces messages d'erreurs, la fonction \textit{dprintk(...)} a
été crée. Cette dernière prend les mêmes paramètres que \textit{printk()} mais n'a son contenu
défini que si l'option de débogage a été choisie dans le menu de configuration du noyau. Ceci
permet d'éviter d'insérer des conditions de préprocesseur pour tous les affichages, ce qui rendrait
le code trop chargé. De plus cette fonction permet d'ajouter automatiquement le préfixe \flqq
OTE\frqq devant chaque message affiché afin de faciliter la recherche dans
le fichier de log. Le label dprintk représente une fonction si l'option de débogage a été cochée ou
une macro ne faisant rien si l'option n'a pas été choisie. Effectivement, plutôt que d'appeler dans
tous les cas la fonction et de tester dans son corps si l'option a été définie, passer par une macro
permet d'économiser les appels à la fonction afin d'optimiser la vitesse d'ordonnancement.
\paragraph{}
Un problème s'est cependant pausé pour la création de cette méthode. Effectivement, une fois
l'ellipse récupérée grâce à la macro \textit{va\_start}, la méthode \textit{vprintk} doit être
appelée à la place de \textit{printk} afin de pouvoir lui passer la liste de type \textit{va\_list}
que \textit{printk} ne peut accepter. Malheureusement cette méthode n'a pas été modifiée pour être
utilisée par Xenomai (au contraire de \textit{printk} qui l'a été). De ce fait un appel à cette
méthode provoquait systématiquement un \textit{kernel panic}.
\paragraph{}
Après plusieurs recherches, un patch permettant de résoudre ce problème a été trouvé
\cite{vprintk:website}. Toutefois ce patch destiné au noyau 2.6.26 de Linux n'est pas fonctionnel
pour notre noyau 2.6.28.7. Malgré tout, il a été possible de modifier manuellement le fichier
concerné (printk.c) afin d'y faire les modifications minimales pour le fonctionnement de cette
fonction. 
\paragraph{}
En outre afin d'accélérer un maximum chaque thread un script pour la recompilation a été créé. Ce
dernier a été placé dans le dossier bin afin de pouvoir l'appeler rapidement depuis n'importe quel
emplacement. Ce script est le suivant :
\lstset{language=bash}
\begin{lstlisting}[frame=trbl]
#!/bin/bash
cd /usr/src/
rm *.deb
cd ./linux-2.6.28.7
sudo make-kpkg --initrd kernel_image kernel_headers
sudo dpkg -r linux-headers-2.6.28.7-xenomai-2.4.7 linux-image-2.6.28.7-xenomai-2.4.7
cd /usr/src
sudo dpkg -i linux-image-2.6.28.7-xenomai-2.4.7_2.6.28.7-xenomai-2.4.7-10.00.Custom_i386.deb
linux-headers-2.6.28.7-xenomai-2.4.7_2.6.28.7-xenomai-2.4.7-10.00.Custom_i386.deb
\end{lstlisting}

\section{Xenomai}
\paragraph{}
Nous verrons dans cette section quels sont les éléments nécessaires dans Xenomai pour effectuer ce
projet. Il est important de souligner que dans Xenomai une tâche \textit{task} est utilisée dans le
mode utilisateur et que, une fois cette tâche reçue dans le noyau, l'ordonnanceur par exemple
utilise uniquement le \textit{thread} contenu dans cette tâche. Ainsi afin de respecter le
vocabulaire de Xenomai nous distinguerons ces deux termes. De plus, avant d'approfondir ce point
par la suite, il faut noté que Xenomai utilise des \textit{timers} logicielles (structures
contenant les informations temporelles) et que sauf précision explicite, le mot timer désignera un
timer logiciel puisque nous travaillons à ce niveau.


\subsection{Structure de Xenomai}
\paragraph{}

Dans Xenomai, un ordonnanceur est représenté à l'aide de la structure \textit{xnsched\_t}. Chaque
CPU du système possède son propre ordonnanceur. Pour récupérer l'ordonnanceur courant, la
fonction \textit{xnpod\_current\_sched()} est disponible. Cette ordonnanceur contient les éléments
nécessaires à l'ordonnancement. On y trouve par exemple la file des éligibles \textit{readyq}, la
files des arrivées \textit{timerqueue}, le thread courante \textit{runthread} mais aussi le timer
hôte \textit{htimer} dont nous reparlons plus tard.
\paragraph{}
Dans le noyau Xenomai, un thread est représentée dans la structure \textit{xnthread\_t}. Cette
structure contient les informations essentielles telles que sa période et sa priorité. Le
thread nommé
\textit{root} est le thread nulle du système. Celle-ci permet au noyau Linux de s'exécuter. Il est
aisé de détecte cette thread en appelant la fonction \textit{xnthread\_test\_state(thread, state)}
dans laquelle est passé comme argument \textit{XNROOT} représentant le thread \textit{root}. Ce test
sera
effectué au début de l'algorithme OTE puisqu'il n'est pas possible d'étendre ce thread. Le thread
\textit{root} permettant au noyau Linux de s'exécuter et ne sachant ce que ce dernier a à effectuer,
nous mettrons le processeur à sa vitesse maximum lorsque ce thread est ordonnancée.
\paragraph{}
La file des éligibles est une file dans laquelle se trouve une file par priorité du système. La
file principale a ses files classées par ordre décroissant (file de plus grande priorité en
premier). Le traitement des égalités est traité selon la politique FIFO, comme nous l'avions évoqué
précédemment au point \ref{file}. La fonction \textit{sched\_getpq} permet de récupérer directement
le thread en tête de la file la plus prioritaire.
\paragraph{}
La file des arrivées est une file simple, classée par date des arrivées croissante. Au contraire de
la file des éligibles, cette file ne contient pas directement les threads. En effet dans cette file
se trouvent les objets de la structure \textit{xntimer\_t} représentant le timer logiciel lié à un
thread. Ce timer contient toutes les informations relatives au temps, comme la période ou la date
de
la prochaine arrivée du thread par exemple. Lorsque le timer matériel se déclenche, la routine
correspondante à l'interruption n'aura plus qu'à récupérer le timer logiciel en tête de cette file.
Une fois ce timer récupéré, une fonction de callback générique est appelée sur ce timer. Dans la
plus part des cas la fonction affectée est une simple fonction permettant de récupérer le thread et
de l'exécuter.
\paragraph{}
Pour récupérer le thread à partir du timer, les développeurs de Xenomai ont utilisé quelques
astuces. Un timer logiciel ne
contient aucune référence sur son thread correspondant. En fait, seul le thread possède un lien sur
le
timer. Lorsqu'il est nécessaire de récupérer le thread à partir du timer, la fonction
\textit{container\_of} est alors utilisée. Cette fonction permet à partir d'un pointeur sur un objet
de récupérer l'objet englobant ce premier objet. En effet, puisqu'on possède un pointeur sur un
timer et que la structure du thread contient un timer il est possible grâce au pointeur de
connaître l'emplacement mémoire du timer. Connaissant aussi la taille de la structure englobante et
l'emplacement dans cette structure du timer, il suffit de soustraire dans la mémoire à partir du
timer la taille entre le timer et le début de la structure pour retrouver l'objet englobant. Cette
opération est évidemment en $O(1)$ et permet de ne pas avoir besoin de mettre à jour les références
des 2 côtés.

\paragraph{}
Pour notre algorithme, il faudra commencer par vérifier si la file des éligibles est vide. Ou
presque vide car le thread allant être ordonnancé est encore dans la file des éligibles puisqu'on
effectue le test avant le changement d'état du thread par la fonction
\textit{xnthread\_clear\_state(...)} C'est pourquoi si le thread est le seule en état prêt, la
taille
de la file sera égale à 1. À noter que le thread spécial root ne se trouve jamais dans cette file.\\

Nous pouvons le constater dans la capture suivante pour le thread trivial2 de priorité 99 et
trivial de priorité 98 :\\
\label{test1}
 \fbox{
\begin{minipage}[t]{15cm} 
[ 2402.111973] Name thread out : trivial\newline
[ 2402.111973] Name thread in : trivial2\newline
[ 2402.111973] nb in queue 2 \newline

[ 2402.111973] Name thread out : trivial2\newline
[ 2402.111973] Name thread in : trivial\newline
[ 2402.111973] nb in queue 1 \newline

[ 2402.111973] Name thread out : trivial\newline
[ 2402.111973] Name thread in : ROOT/0\newline
[ 2402.111973] nb in queue 0 \newline

[ 2422.884896] Name thread out : ROOT/0\newline
[ 2422.884902] Name thread in : trivial\newline
[ 2422.884908] nb in queue 1
\end{minipage} 
 }


\paragraph{}
Le timer hôte, qu'on peut voir ici à la $3^{eme}$ ligne, représente en fait dans ce cas le thread
nulle, soit le thread \textit{root} qui permet au noyau Linux de s'exécuter. Ce timer n'est donc pas
un véritable timer puisqu'il n'est pas lié à un événement périodique (dans notre contexte
puisqu'aucun thread
Linux n'est sensé être périodique). De ce fait, ce timer ne doit pas être pris en compte lors de
la recherche du prochain thread à exécuter. 

\subsection{Prochain thread}
\paragraph{}
Comme étudié précédemment, afin de pouvoir étendre la durée d'une instance d'un thread, il est
nécessaire de connaître son échéance et la date d'arrivée de la prochaine instance qui va
arriver. Toutefois, dans Xenomai, lorsque l'instance d'un thread passe de la file des arrivées à la
file des
éligibles, la prochaine instance de ce thread est directement inséré dans la file des arrivées.
Ainsi lors du changement de file, 2 instances existent en même temps : l'instance courante
dans la file des éligibles et la prochaine instance du thread dans la file des arrivées. Ceci nous
permet de ne pas nous soucier, pour OTE, de l'échéance de l'instance du thread puisque
lors du test de la prochaine arrivée dans la file des éligibles, la futur instance s'y trouve
déjà et sera pris en compte comme les autres instances pour calculer le temps libre à disposition.
Pour preuve voici le résultat obtenu lors de l'ordonnancement du thread trivial2 :\\
\label{test2}
 \fbox{
\begin{minipage}[t]{15cm} 
[  355.297343] Ingoing thread name : trivial2\newline
[  355.297349] Next arrivals : trivial\newline
[  355.297355] Next arrivals : [host-timer/0]\newline
[  355.297361] Next arrivals : trivial2
\end{minipage} 
 }
\newline
\newline
Pendant que l'instance courante à la première ligne est ordonnancée, la dernière ligne
représente la prochaine instance du thread trivial2. De ce fait si le thread est tout seul, il
aura comme temps à disposition sa période moins son temps d'exécution.



\section{Algorithme}

Dans notre algorithme 3 cas principaux peuvent survenir :\\
\label{CasPrincipaux}
\begin{enumerate}
 \item
Avec un thread $T1$ et $T2$ qui arrivent et avec $prio(T1) > prio(T2)$ : \\
$T2$ passe en mode prêt alors que $T1$ s'exécute.\\
Lorsque $T1$ termine, il reste uniquement $T2$ dans la file des éligibles. $T2$ pourra
ainsi s'étendre (taille(file) = 1) si le temps à disposition est assez grand.
 \item
$T1$ passe en mode prêt pendant que $T2$ s'exécute.\\
$T2$ est alors préempté au profit de $T1$. Il y a donc $T1$ et $T2$ dans la file des éligibles
puisque $T2$ désire encore se faire exécuter (taille(file) = 2). $T1$ ne pourra donc pas s'étendre.

 \item
Aucun thread n'est prêt et $T1$ ou $T2$ passe en mode prêt.\\ 
Le thread est alors seul et peut s'étendre (taille(file) = 1) si le temps à disposition est assez
grand.
\end{enumerate}
\paragraph{}
La généralisation à n threads ne change pas le problème. Puisque dès lors qu'un thread n'est pas
seul il ne pourra s'étendre, qu'elle que soit sa priorité.
\paragraph{}
Par ailleurs, comme mentionné précédemment c.f.\ref{TempsRestant}, il sera nécessaire de mettre à
jour le temps d'exécution restant dans le cas 2, lorsqu'un thread est préempté.
Pour ce faire, il faudra vérifier si le thread sortant a fini son traitement ou a été préempté par
un autre thread et doit continuer son exécution. Pour calculer le temps d'exécution restant, il
faudra insérer dans toutes les instances des threads, sauf le thread root, la date du début de
l'exécution courante de l'instance. Précisons que l'instance d'un thread peut être exécutée
plusieurs fois en cas de préemption et qu'à chacune de ses exécutions, le temps de début y sera
inséré. Chaque instance possédera ainsi, en plus de ses variables actuelles, la date du début
d'exécution, le temps d'exécution restant et le WCET. Il va de soit que le temps restant est à
chaque nouvelle instance, réinitialiser à la valeur du WCET.
\paragraph{}
Lors de la préemption du thread, si il reste en état prêt, c'est que cet dernier n'a pas
terminé son travail. C'est pourquoi nous devrons mettre à jour son temps restant en soustrayant à
ce dernier la date actuelle moins celle du début d'exécution. Soit pour calculer le temps
restant de l'instance j d'un thread T :\\
$TempsRestant(T_{j}) := TempsRestant(T_{j}) - (DateActuelle - DebutExec(T_{j}))$

\section{CPU}
\paragraph{}
Pour pouvoir changer la fréquence du processeur, il est nécessaire de posséder le datasheet pour
connaitre les registres à manipuler mais aussi les correspondances fréquences / tensions.
Malheureusement, après plusieurs correspondances avec VIA, ces derniers n'ont jamais accepté de
nous fournir ces informations. Toutefois l'entreprise nous ayant vendu le matériel nous a fourni
quelques informations. Informations comprenant les registres à utiliser, les numéros correspondant
au tensions données (table de correspondances) ainsi que les 2 fréquences et tensions
supportées officiellement \ref{infoVIA}. Cependant ces derniers ne nous ont aucunement fourni des
renseignement sur le ratio de vitesse.
\paragraph{}
La carte mère fourni une fréquence via sa PLL que le processeur multiplie afin d'obtenir la
fréquence désirée. Ce multiplicateur, soit le ratio, doit donc être connu pour obtenir la fréquence
voulue. Puisque nous n'avons pas ces informations, et que le processeur tourne à ça vitesse
maximum (1000Mhz dans notre cas), ceci car le changement de fréquence a dû être désactivé à la
compilation afin que Linux ne puisse changer de fréquence, il est donc possible de lire les
registres du CPU afin de connaître la valeur du ratio pour la fréquence maximum.\\ 

Les valeurs du registre sont formatées ainsi :

\begin{tabular}{|l|l|}
\hline
8 bits & 8 bits\\
\hline
ratio & n° tension\\
\hline
\end{tabular}
\newline

Ainsi pour 1000Mhz le résultat était le suivant (hexadécimal) :

\begin{tabular}{|l|l|}
\hline
0A & 13\\
\hline
\end{tabular}

\paragraph{}
On peut constater que la tension, numéro 13, correspond à 1.04V dans la figure 21 de \ref{infoVIA},
ce qui correspond au données fournies. Le ratio est de 0A soit 10 en décimal. Puisque la fréquence
est de 1000Mhz on peut en déduire que la fréquence de base est de $\displaystyle\frac{1000Mhz}{10} =
100Mhz$ et ainsi pour obtenir une fréquence de 800Mhz le ratio est de 08.
\paragraph{}
Toutefois après avoir effectué plusieurs test de vitesse en exécutant un thread avec un ratio de 10
puis de 8, la différence de temps d'exécution était de l'ordre de 2\% plus rapide pour le ratio de
10 au lieu des 20\% attendu. Les instructions du constructeur sont donc nécessaires. Ajoutons que
plusieurs autres ratios et tensions ont été testés. Pour un ratio de 16 par exemple lors de la
relecture de la vitesse du CPU, le ratio indiqué était de 10. De même pour un ratio plus petit, 4
par
exemple, nous redonnais 8. C'est pourquoi les ratios 8 et 10 semblent correct et l'erreur provient
peut-être de la tension même si celle-ci est donnée dans les informations fournies par le vendeur.

\subsection{Instruction CPU}
\paragraph{}
Dans l'optique de changer de fréquence le CPU, nous avons commencé par essayer d'utiliser
directement le module \textit{cpufreq} du noyau Linux par la fonction cpufreq\_get\_policy(...) pour
récupérer les informations du CPU. Toutefois, il ne semble pas possible d'appeler un module chargé
dans le noyau Linux via Xenomai. En effet ce type d'opérations provoquait instantanément un
\textit{kernel panic} soit un crash du noyau.
\paragraph{}
Nous avons donc récupéré du code du noyau Linux. Effectivement, Linux possède déjà des librairies
prévue pour ce type de processeur. Toutefois afin
de ne pas devoir inclure des dizaines de librairies, nous avons inclus uniquement celle contenant le
code assembleur. Pour le reste nous avons repris la partie de code s'occupant du changement de
fréquence que nous avons remodelé afin d'effectuer uniquement les opérations nécessaires et afin
d'enlever le maximum de références sur d'autres fichiers d'en-tête (suppression de structures
remplacées par de simples entiers, etc).



\section{Pour l'utilisateur}
\paragraph{}
Afin de pouvoir activéer l'option OTE, cette dernière a été ajoutée dans le menu de configuration du
noyau. Pour ce faire une nouvelle entrée a été ajoutée dans le fichier Kconfig. Puisque cette
option nécessite le mode périodique, l'option n'est disponible qu'après avoir activé ce dernier
mode. Ensuite, un appel système a été ajouté afin de pouvoir paramétrer le WCET du thread. En
reprenant la même façon de faire que les développeur de Xenomai pour passer le \textit{time slice}
pour Round Robin. Cette fonction se nomme \textit{rt\_task\_wcet(...)} et a été ajoutée à l'API.


\section{Tests}
\paragraph{}
Cette section a pour but de présenter les tests de validation du projet. Des tests ont déjà été
effectués tout au long du projet puisqu'il s'agissait essentiellement d'un projet
de recherche. Chaque file, chaque valeur, chaque fonction ont été testées, leurs valeurs
inspectées et comparées afin de trouver les résultats attendus. Ainsi il a fallu
beaucoup de tests avant de trouver les bons résultats. Test infructueux qui n'apporterait rien au
lecteur. Même si quelques résultats de tests ont déjà été exposés au cours des sections
précédentes \ref{test1,test2}. Pour pouvoir afficher les informations de débogage, il est nécessaire
d'activer l'option adéquate
lors de la compilation du noyau \ref{debug}.
\subsection{Test du thread root}
Ce test a pour but de vérifier si le thread root est bien ignoré :\\

\fbox{
\begin{minipage}[t]{15cm} 
OTE : -------------------------------------------\\
OTE : Ingoing thread name : ROOT/0\\
OTE : Outgoing thread name : T1\\
OTE : Listing of all threads in the arrival queue\\
OTE : Timer name : [host-timer/0]\\
OTE : Corresponding thread name : \\
OTE : Timer name : T1\\
OTE : Corresponding thread name : T1\\
OTE : Timer name : T2\\
OTE : Corresponding thread name : T2\\
OTE : End of listing\\
OTE : OTE : The current time is : 300810086438\\
OTE : This is the root thread\\
OTE : Thread duration not extended with frequency ratio at : A\\
OTE : Thread duration not extended with voltage num : 13\\
OTE : -------------------------------------------
\end{minipage}
}
\subsection{Temps restant}
Le thread T1 commenc son exécution. Il voit que T2 va arriver et ne peut donc pas s'étendre :\\
\fbox{
\begin{minipage}[t]{15cm} 
OTE : -------------------------------------------\\
OTE : Ingoing thread name : T1\\
OTE : Outgoing thread name : ROOT/0\\
OTE : Listing of all threads in the arrival queue\\
OTE : Timer name : [host-timer/0]\\
OTE : Corresponding thread name : \\
OTE : Timer name : T2\\
OTE : Corresponding thread name : T2\\
OTE : End of listing\\
OTE : OTE : The current time is : 260750697868\\
OTE : The thread T2 will fire at : 262750259856\\
OTE : The remaining time of the current thread T1 is : 3000000000\\
OTE : Not enough free time available\\
OTE : Thread duration not extended with frequency ratio at : A\\
OTE : Thread duration not extended with voltage num : 13\\
OTE : -------------------------------------------
\end{minipage}
}
\newline
\newline
\newline
Le thread T2 ayant une priorité suppérieure à T1 préempte ce dernier. Puisque le thread T1 n'a pas
fini son exécution, 2 threads sont maintenent dans la file des éligibles et T2 ne peut s'étendre.\\
\fbox{
\begin{minipage}[t]{15cm} 
OTE : -------------------------------------------\\
OTE : Ingoing thread name : T2\\
OTE : Outgoing thread name : T1\\
OTE : Listing of all threads in the arrival queue\\
OTE : Timer name : [host-timer/0]\\
OTE : Corresponding thread name : \\
OTE : Timer name : T1\\
OTE : Corresponding thread name : T1\\
OTE : Timer name : T2\\
OTE : Corresponding thread name : T2\\
OTE : End of listing\\
OTE : OTE : The current time is : 262750274111\\
OTE : There are 2 threads ready\\
OTE : Thread duration not extended with frequency ratio at : A\\
OTE : Thread duration not extended with voltage num : 13\\
OTE : -------------------------------------------
\end{minipage}
}
\newline
\newline
\newline
Une fois que le thread T2 a terminé son exécution, le thread T1 reprend son exécution. 
Comme on peut facilement le vérifier, le thread T1 a commencé son exécution à
260750697868 et la terminée à 262750274111 ce qui nous donne un temps d'exécution de 1999576243.
Son WCET étant de 3000000000 son temps restant doit donc être de 1000423757. Ce qui est bien le cas.
Le temps libre étant suffisant pour exécuter son temps restant, la durée du thread peut être
étendue.\\
\fbox{
\begin{minipage}[t]{15cm} 
OTE : -------------------------------------------
OTE : Ingoing thread name : T1
OTE : Outgoing thread name : T2
OTE : Listing of all threads in the arrival queue
OTE : Timer name : [host-timer/0]
OTE : Corresponding thread name : 
OTE : Timer name : T1
OTE : Corresponding thread name : T1
OTE : Timer name : T2
OTE : Corresponding thread name : T2
OTE : End of listing
OTE : OTE : The current time is : 262750303541
OTE : The thread T1 will fire at : 270750204549
OTE : The remaining time of the current thread T1 is : 1000423757
OTE : The free time available is : 7999901008
OTE : Thread duration extended with frequency ratio at : 8
OTE : Thread duration extended with voltage num : 10
OTE : -------------------------------------------
 \end{minipage}
}
\newline
\newline
\newline
Ce dernier test a passé en revue toutes les fonctionnalités de l'algorithme pas encore testées
soitent : Pas assez de temps libre pour étendre, extension après réordonnamcement de la même
instance et finalement plusieurs tâches dans la files des éligibles.

\paragraph{}
Dans le chapitre suivant nous sortirons du contexte technique pour s'intéresser
à l'état du projet lui même.





